﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Collections;
using System.Reflection;

namespace TRPOP.Common
{
     /// <summary>
    /// 主要用于辅助Model层，如加截reader数据到List
    /// </summary>
    public class ModelHelper
    {
        #region 根据数据类型，获得的该类型的所有属性 GetFieldPropertiesByFieldType

        /// <summary>
        /// 根据数据类型，获得的该类型的所有属性
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        static public Hashtable GetPropertiesFromInfoByFieldType(object obj, FieldType type)
        {
            Type myType = obj.GetType();
            PropertyInfo[] m = myType.GetProperties();//获得所有公共属性

            Hashtable hProps = new Hashtable();
            foreach (PropertyInfo p in m)
            {
                DataAttribute[] a = (DataAttribute[])p.GetCustomAttributes(typeof(DataAttribute), true);
                foreach (DataAttribute t in a)
                {
                    int m1 = (int)t.Type;
                    int n1 = (int)type;
                    if (((m1 ^ n1) & n1) == 0)
                    //if(((int)t.Type&(int)type)>0)
                    {
                        hProps.Add(p.Name.ToLower(), p);
                    }
                }
            }
            return hProps;
        }
        #endregion

        #region 公共方法

        /// <summary>
        /// 根据DataReader为对实体赋值
        /// </summary>
        /// <param name="obj">调用实体</param>
        /// <param name="reader">实体属性值</param>
        /// <returns></returns>
        static public void LoadInfoData(Object obj, IDataReader reader)
        {

            Hashtable cols = new Hashtable();
            for (int i = 0; i < reader.FieldCount; i++)
            {
                cols.Add(reader.GetName(i).ToLower(), reader.GetValue(i));	//装入数据到hashtable中
            }
            Hashtable h = GetPropertiesFromInfoByFieldType(obj, FieldType.DBField);	//获取属性的Hasttable
            foreach (Object o in h.Keys)
            {
                PropertyInfo p = (PropertyInfo)h[o];
                Object v = null;


                if (cols.Contains(o))
                {
                    v = cols[o];
                }

                if (v != null)
                {
                    SetPropertyValue(ref obj, ref p, ref v);
                }
            }
        }
        #endregion

        #region 为属性进行赋值操作 SetPropertyValue

        /// <summary>
        /// 为属性进行赋值操作
        /// </summary>
        /// <param name="obj">设置其属性 (Property) 值的对象</param>
        /// <param name="p">要赋值的属性</param>
        /// <param name="v">值</param>
        static protected void SetPropertyValue(ref Object obj, ref PropertyInfo p, ref Object v)
        {
            try
            {
                if (p.PropertyType == typeof(Int32))
                {
                    p.SetValue(obj, Int32.Parse(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(Decimal))
                {
                    p.SetValue(obj, Decimal.Parse(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(Guid))
                {
                    p.SetValue(obj, new Guid(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(Single))
                {
                    p.SetValue(obj, Single.Parse(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(Double))
                {
                    p.SetValue(obj, Double.Parse(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(DateTime))
                {
                    p.SetValue(obj, DateTime.Parse(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(Boolean))
                {
                    p.SetValue(obj, Boolean.Parse(v.ToString()), null);
                }
                else if (p.PropertyType == typeof(Byte))
                {
                    p.SetValue(obj, Byte.Parse(v.ToString()), null);
                }
                else
                {
                    p.SetValue(obj, v.ToString(), null);
                }
            }
            catch (Exception oeException)
            {
                throw new Exception("属性赋值发生异常" + oeException.Message, oeException);
            }
        }
        #endregion

    }

    /// <summary>
    /// 属性字段类型，数据库字段、显示、表单录入值等
    /// </summary>
    public enum FieldType
    {
        /// <summary>
        /// 
        /// </summary>
        DBField = 0x1, //数据库字段
    }

    /// <summary>
    /// 实体类属性
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class DataAttribute : Attribute
    {
        private FieldType m_oFieldType;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldType"></param>
        public DataAttribute(FieldType fieldType)
        {
            m_oFieldType = fieldType;
        }
        /// <summary>
        /// 
        /// </summary>
        public FieldType Type
        {
            set { m_oFieldType = value; }
            get { return m_oFieldType; }
        }
    }
}
